home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / prefix / prefix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-25  |  12.3 KB  |  466 lines

  1. /* 
  2.  * prefix.c --
  3.  *
  4.  *    Program to print and manipulate the prefix table.
  5.  *
  6.  * Copyright 1988 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/cmds/prefix/RCS/prefix.c,v 1.11 92/03/25 15:53:12 shirriff Exp $ SPRITE (Berkeley)";
  18. #endif not lint
  19.  
  20. #include <fs.h>
  21. #include <fsCmd.h>
  22. #include <host.h>
  23. #include <option.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <status.h>
  27. #include <sysStats.h>
  28. #include <sys/stat.h>
  29.  
  30. static int PrintPrefixEntry _ARGS_ ((Fs_Prefix *prefixPtr));
  31. static void validateLocalPath _ARGS_ ((char *path, int checkRemote));
  32.  
  33. extern int errno;
  34. static char *programName;
  35.  
  36. /*
  37.  * Command line options.
  38.  */
  39.  
  40. static int print = 0;
  41. static int readOnly = 0;
  42. static int localAccess = 0;
  43. static int force = 0;
  44. static char *loadedPrefix = (char *) NULL;
  45. static char *deviceName = (char *) NULL;
  46. static char *unmountName = (char *) NULL;
  47. static char *exportedPrefix = (char *) NULL;
  48. static char *clearedPrefix = (char *) NULL;
  49. static char *deletedPrefix = (char *) NULL;
  50. static char *Prefix = (char *) NULL;
  51. static char *localPath = (char *) NULL;
  52. static char *addHostName = NULL;
  53. static char *delHostName = NULL;
  54. static char *serverName = NULL;
  55.  
  56. static Option optionArray[] = {
  57.     {OPT_TRUE,   "p", (char *) &print,
  58.     "Print the prefix table or export list"},
  59.     {OPT_STRING, "a", (char *) &loadedPrefix,
  60.     "Next argument is prefix to add"},
  61.     {OPT_STRING,  "s", (char *) &serverName,
  62.     "Next argument is name or id of server for added prefix (use with -a)"},
  63.     {OPT_STRING, "l", (char *) &localPath,
  64.     "Next argument is directory to mount/export (with -x, -M or -U)"},
  65.     {OPT_STRING, "M", (char *) &deviceName,
  66.     "Next argument is device to mount (use -l too)"},
  67.     {OPT_TRUE,     "r", (char *) &readOnly,
  68.     "Mount read only"},
  69.     {OPT_TRUE,     "f", (char *) &force,
  70.     "Force the mount"},
  71.     {OPT_TRUE,     "L", (char *) &localAccess,
  72.     "Mount locally only; do not export"},
  73.     {OPT_STRING, "U", (char *) &unmountName,
  74.     "Next argument is prefix to unmount"},
  75.     {OPT_STRING, "x", (char *) &exportedPrefix, 
  76.     "Next argument is exported prefix (use with -p, -l, or -[hH])"},
  77.     {OPT_STRING, "h", (char *) &addHostName,
  78.     "Next argument is name or id of host to add to export list"},
  79.     {OPT_STRING, "H", (char *) &delHostName,
  80.     "Next argument is name or id of host to delete from export list"},
  81.     {OPT_STRING, "c", (char *) &clearedPrefix,
  82.     "Next argument is prefix to clear handle for"},
  83.     {OPT_STRING, "d", (char *) &deletedPrefix, 
  84.     "Next argument is prefix to delete altogether"},
  85. };
  86.  
  87.  
  88.  
  89. /*
  90.  *----------------------------------------------------------------------
  91.  *
  92.  * main --
  93.  *
  94.  *    Collects arguments and uses Fs_Command to manipulate the
  95.  *    prefix table.
  96.  *
  97.  * Results:
  98.  *    None.
  99.  *
  100.  * Side effects:
  101.  *    Calls Fs_Command...
  102.  *
  103.  *----------------------------------------------------------------------
  104.  */
  105.  
  106. main(argc, argv)
  107.     int argc;
  108.     char *argv[];
  109. {
  110.     register     ReturnStatus status = SUCCESS;    /* status of system calls */
  111.     int     flags;
  112.     int     addHostID = -1;
  113.     int     delHostID = -1;
  114.     int     serverID = FS_NO_SERVER;
  115.     Host_Entry    *entry;
  116.     int        scanned;
  117.     int        temp;
  118.  
  119.     programName = argv[0];
  120.     if (argc == 1) {
  121.     print = 1;
  122.     } else {
  123.     argc = Opt_Parse(argc, argv, optionArray, Opt_Number(optionArray),
  124.         OPT_ALLOW_CLUSTERING);
  125.     }
  126.  
  127.     if (argc != 1) {
  128.     fprintf(stderr, "%s got extraneous argument \"%s\".\n", argv[0],
  129.         argv[1]);
  130.     Opt_PrintUsage(argv[0], optionArray, Opt_Number(optionArray));
  131.     exit(1);
  132.     }
  133.     if (addHostName != (char *) NULL) {
  134.     scanned = sscanf(addHostName, " %d", &temp);
  135.     if (scanned == 1) {
  136.         addHostID = temp;
  137.     } else {
  138.         entry = Host_ByName(addHostName);
  139.         if (entry == NULL) {
  140.         fprintf(stderr, "No such host \"%s\"\n", addHostName);
  141.         exit(1);
  142.         }
  143.         addHostID = entry->id;
  144.     }
  145.     }
  146.     if (delHostName != (char *) NULL) {
  147.     scanned = sscanf(delHostName, " %d", &temp);
  148.     if (scanned == 1) {
  149.         delHostID = temp;
  150.     } else {
  151.         entry = Host_ByName(delHostName);
  152.         if (entry == NULL) {
  153.         fprintf(stderr, "No such host \"%s\"\n", delHostName);
  154.         exit(1);
  155.         }
  156.         delHostID = entry->id;
  157.     }
  158.     }
  159.     if (serverName != (char *) NULL) {
  160.     scanned = sscanf(serverName, " %d", &temp);
  161.     if (scanned == 1) {
  162.         serverID = temp;
  163.     } else {
  164.         entry = Host_ByName(serverName);
  165.         if (entry == NULL) {
  166.         fprintf(stderr, "No such host \"%s\"\n", serverName);
  167.         exit(1);
  168.         }
  169.         serverID = entry->id;
  170.     }
  171.     }
  172.     if (loadedPrefix != (char *) NULL) {
  173.     /*
  174.      * Load a prefix
  175.      *    Load a prefix into the prefix table.
  176.      *    A prefix in the prefix table causes an attempt to find the
  177.      *    server the first time a file is opened under that prefix.
  178.      *      If serverID == FS_NO_SERVER then a broadcast is done,
  179.      *    otherwise the server is contacted directly.
  180.      */
  181.     Fs_PrefixLoadInfo    loadInfo;
  182.  
  183.     (void) strcpy(loadInfo.prefix, loadedPrefix);
  184.     loadInfo.serverID = serverID;
  185.     status = Fs_Command(FS_PREFIX_LOAD, sizeof(Fs_PrefixLoadInfo), 
  186.          &loadInfo);
  187.     if (status != SUCCESS) {
  188.         fprintf(stderr, "%s couldn't load prefix: %s.\n",
  189.             argv[0], Stat_GetMsg(status));
  190.         exit(1);
  191.     }
  192.     }
  193.     if (deviceName != (char *)NULL) {
  194.     if (!force) {
  195.         validateLocalPath(localPath, 1);
  196.     }
  197.     flags = 0;
  198.     if (localAccess) {
  199.         flags |= FS_ATTACH_LOCAL;
  200.     }
  201.     if (readOnly) {
  202.         flags |= FS_ATTACH_READ_ONLY;
  203.     }
  204.     status = Fs_AttachDisk(deviceName, localPath, flags);
  205.     if (status != SUCCESS) {
  206.         fprintf(stderr, "Mount \"%s\" on \"%s\": %s\n", deviceName,
  207.             localPath, Stat_GetMsg(status));
  208.         exit(1);
  209.     }
  210.     localPath = (char *)NULL;
  211.     }
  212.     if (unmountName != (char *)NULL) {
  213.     status = Fs_AttachDisk(deviceName, unmountName, FS_DETACH);
  214.     if (status != SUCCESS) {
  215.         fprintf(stderr, "Unmount \"%s\": %s\n", unmountName,
  216.             Stat_GetMsg(status));
  217.         exit(1);
  218.     }
  219.     }
  220.     if (addHostID != -1 || delHostID != -1) {
  221.     Fs_PrefixControl    prefixControl;
  222.     /*
  223.      * Add or remove a host from a prefix's export list.
  224.      */
  225.     if (exportedPrefix == (char *) NULL) {
  226.         fprintf(stderr, "Specify an exported prefix with -x\n");
  227.         Opt_PrintUsage(argv[0], optionArray, Opt_Number(optionArray));
  228.         exit(1);
  229.     }
  230.     if (addHostID != -1) {
  231.         prefixControl.clientID = addHostID;
  232.         prefixControl.delete = FALSE;
  233.     } else {
  234.         prefixControl.clientID = delHostID;
  235.         prefixControl.delete = TRUE;
  236.     }
  237.     (void) strcpy(prefixControl.prefix, exportedPrefix);
  238.     status = Fs_Command(FS_PREFIX_CONTROL, sizeof(prefixControl),
  239.         &prefixControl);
  240.     if (status != SUCCESS) {
  241.         fprintf(stderr, "%s couldn't add/delete host: %s.\n",
  242.             argv[0], Stat_GetMsg(status));
  243.         exit(1);
  244.     }
  245.     exportedPrefix = (char *) NULL;
  246.     }
  247.     if (exportedPrefix != (char *) NULL) {
  248.     if (print) {
  249.         /*
  250.          * Print the export list of this prefix.
  251.          */
  252.         char buffer[100 * sizeof(int)];
  253.         int *exportList = (int *)buffer;
  254.         (void) strcpy(buffer, exportedPrefix);
  255.         status = Sys_Stats(SYS_FS_PREFIX_EXPORT, sizeof(buffer), buffer);
  256.         if (status != SUCCESS) {
  257.         fprintf(stderr, "%s: couldn't get export list\n",
  258.             exportedPrefix);
  259.         exit(status);
  260.         } else if (*exportList == 0) {
  261.         printf("%s exported to all hosts\n", exportedPrefix);
  262.         } else {
  263.         printf("\"%s\" EXPORT LIST\n", exportedPrefix);
  264.         for ( ; *exportList != 0 ; exportList++) {
  265.             Host_Entry *hostPtr;
  266.             hostPtr = Host_ByID(*exportList);
  267.             if (hostPtr == (Host_Entry *)NULL) {
  268.             break;
  269.             }
  270.             printf("\t<%d> %s\n", hostPtr->id, hostPtr->name);
  271.         }
  272.         }
  273.     } else {
  274.         Fs_TwoPaths args;
  275.  
  276.         /*
  277.          * localPath may be "/", a real directory, when the
  278.          * -x option is used so disable the remote link check
  279.          * in validateLocalPath
  280.          */
  281.         if (!force) {
  282.         validateLocalPath(localPath, 0);
  283.         }
  284.  
  285.         /*
  286.          * Export a prefix.  This is used on a server to explicitly
  287.          * export a local directory under some prefix.
  288.          */
  289.     
  290.         args.pathLen1 = strlen(localPath) + 1;
  291.         args.path1 = localPath;
  292.         args.pathLen2 = strlen(exportedPrefix) + 1;
  293.         args.path2 = exportedPrefix;
  294.     
  295.         status = Fs_Command(FS_PREFIX_EXPORT, sizeof(Fs_TwoPaths), &args);
  296.         if (status != SUCCESS) {
  297.         fprintf(stderr, "%s couldn't export prefix: %s.\n",
  298.             argv[0], Stat_GetMsg(status));
  299.         exit(1);
  300.         }
  301.     }
  302.     }
  303.     if (clearedPrefix != (char *) NULL) {
  304.     /*
  305.      * Clear a prefix's file handle.
  306.      */
  307.     status = Fs_Command(FS_PREFIX_CLEAR, strlen(clearedPrefix) + 1,
  308.         clearedPrefix);
  309.     if (status != SUCCESS) {
  310.         fprintf(stderr, "%s couldn't clear prefix handle: %s.\n",
  311.             argv[0], Stat_GetMsg(status));
  312.         exit(1);
  313.     }
  314.     }
  315.     if (deletedPrefix != (char *) NULL) {
  316.     /*
  317.      * Delete a prefix
  318.      */
  319.     status = Fs_Command(FS_PREFIX_DELETE, strlen(deletedPrefix) + 1,
  320.         deletedPrefix);
  321.     if (status != SUCCESS) {
  322.         fprintf(stderr, "%s couldn't delete prefix: %s.\n",
  323.             argv[0], Stat_GetMsg(status));
  324.         exit(1);
  325.     }
  326.     }
  327.     if (print) {
  328.     register int index;
  329.     Fs_Prefix prefix;
  330.  
  331.     printf("%-20s %-8s %7s %7s %8s\n", 
  332.         "Prefix", "Server", "Domain", "File #", "Version");
  333.     for (index = 0 ; status == SUCCESS; index++) {
  334.         bzero((char *) &prefix, sizeof(Fs_Prefix));
  335.         status = Sys_Stats(SYS_FS_PREFIX_STATS, index, (Address) &prefix);
  336.         if (status == SUCCESS) {
  337.         PrintPrefixEntry(&prefix);
  338.         }
  339.     }
  340.     }
  341.     exit(0);
  342. }
  343.  
  344. /*
  345.  *----------------------------------------------------------------------
  346.  *
  347.  * PrintPrefixEntry --
  348.  *
  349.  *    Print out information for a single prefix table entry.
  350.  *
  351.  * Results:
  352.  *    None.
  353.  *
  354.  * Side effects:
  355.  *    Stuff gets printed.
  356.  *
  357.  *----------------------------------------------------------------------
  358.  */
  359.  
  360. static int 
  361. PrintPrefixEntry(prefixPtr)
  362.     Fs_Prefix *prefixPtr;
  363. {
  364.     static char serverName[9];
  365.     static int  prevServerID = -1;
  366.     Host_Entry  *host;
  367.  
  368.     printf("%-20s", prefixPtr->prefix);
  369.  
  370.     if (prefixPtr->serverID > 0) {
  371.  
  372.     /*
  373.      * If the server ID is the same as the previous entry's ID, then
  374.      * we can reuse serverName and save a call to Host_ByID.
  375.      */
  376.     if (prefixPtr->serverID == prevServerID) {
  377.         printf(" %-8s", serverName);
  378.     } else {
  379.         host = Host_ByID(prefixPtr->serverID);
  380.         if (host != (Host_Entry *)NULL) {
  381.         register int charCnt;
  382.         for (charCnt = 0 ; charCnt < sizeof(serverName) ; charCnt++) {
  383.             if (host->name[charCnt] == '.' ||
  384.             host->name[charCnt] == '\0') {
  385.             serverName[charCnt] = '\0';
  386.             break;
  387.             } else {
  388.             serverName[charCnt] = host->name[charCnt];
  389.             }
  390.         }
  391.         serverName[sizeof(serverName)-1] = '\0';
  392.         printf(" %-8s", serverName);
  393.         prevServerID = prefixPtr->serverID;
  394.         } else {
  395.         printf(" (%d)", prefixPtr->serverID);
  396.         }
  397.     }
  398.     } else {
  399.     printf(" %-8s", "(none)");
  400.     }
  401.  
  402.     printf(" %7d %7d %8d", prefixPtr->domain, prefixPtr->fileNumber, 
  403.         prefixPtr->version);
  404.  
  405.     if (prefixPtr->flags & FS_LOCAL_PREFIX) {
  406.     printf(" local   ");
  407.     }
  408.     if (prefixPtr->flags & FS_IMPORTED_PREFIX) {
  409.     printf(" imported");
  410.     }
  411.     if (prefixPtr->flags & FS_EXPORTED_PREFIX) {
  412.     printf(" exported");
  413.     }
  414.     printf("\n");
  415. }
  416.  
  417. /*
  418.  *----------------------------------------------------------------------
  419.  *
  420.  * validateLocalPath --
  421.  *
  422.  *    Make sure the local path specified with the -l option is valid.
  423.  *    It must be an absolute path starting with '/'.
  424.  *      It must be an already existing remote link if checkRemote == 1.
  425.  *
  426.  * Results:
  427.  *    None.
  428.  *
  429.  * Side effects:
  430.  *    Will exit with an error code of 1 if the path is invalid.
  431.  *
  432.  *----------------------------------------------------------------------
  433.  */
  434.  
  435. static void
  436. validateLocalPath(path, checkRemote)
  437.     char *path;
  438.     int checkRemote;
  439. {
  440.     struct stat statBuf;
  441.  
  442.     if (path == NULL) {
  443.     fprintf(stderr, "%s:  You must specify a local directory with -l\n",
  444.         programName);
  445.     Opt_PrintUsage(programName, optionArray, Opt_Number(optionArray));
  446.     exit(1);
  447.     } else if (*path != '/') {
  448.     fprintf(stderr,
  449.         "%s:  %s is not an absolute path.  It must start with '/'\n",
  450.         programName, path);
  451.     exit(1);
  452.     }
  453.     if (lstat(path, &statBuf) < 0) {
  454.     fprintf(stderr, "%s:  Cannot lstat %s:  %s\n",
  455.         programName, path, strerror(errno));
  456.     exit(1);
  457.     }
  458.     if (checkRemote && (statBuf.st_mode & S_IFMT) != S_IFRLNK) {
  459.     fprintf(stderr, "%s:  %s is not a remote link.\n",
  460.         programName, path);
  461.     exit(1);
  462.     }
  463.     return;
  464. }
  465.  
  466.